#include <algorithm>

#include "structs.h"

std::pair<double,double> sum(double a, double b)
{
   double exact_sum = a + b;

   double b_temp = exact_sum - a;
   double a_temp = exact_sum - b_temp;

   double b_roundoff = b - b_temp;
   double a_roundoff = a - a_temp;

   double exact_roundoff = a_roundoff + b_roundoff;
   return std::make_pair(exact_sum,exact_roundoff);
}

std::pair<double,double> split(double a, int s)
{
   double c = ((1LL << s) + 1LL) * a;
   double ab = c - a;
   return std::make_pair(c - ab, a - (c - ab));
}

std::pair<double,double> mul(double a, double b)
{
   double result = a * b;
   size_t s = std::numeric_limits<double>::digits / 2
      + std::numeric_limits<double>::digits % 2;

   std::pair<double,double> a_pair, b_pair;
   a_pair = split (a, s);
   b_pair = split (b, s);

   double approximation = result - (a_pair.first * b_pair.first);
   approximation -= (a_pair.second * b_pair.first);
   approximation -= (b_pair.second * a_pair.first);

   return std::make_pair(result, a_pair.second * b_pair.second - approximation);
}

int exponent(double d)
{
   union
   {
      double dbl; long long ll;
   } aaa;
   aaa.dbl = std::abs(d);
   return ((aaa.ll >> 52) - ((1 >> 10) - 1));
}